package com.request.service.impl.shop.kx;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.request.common.constants.RedisConstant;
import com.request.common.enums.SignTypeEnum;
import com.request.common.utils.HttpUtils;
import com.request.common.utils.SignUtils;
import com.request.entity.PhoneOrderAvailable;
import com.request.entity.PhoneOrderWaitPush;
import com.request.entity.out.PushOrderForKxDistribute;
import com.request.entity.out.PushPackageOrderForKxDistribute;
import com.request.service.PushPackageOrderProcessor;
import com.request.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * Description:
 * Create DateTime: 2020/9/14 13:11
 *
 * 

 */
@Service
@Slf4j
public class KxDistributePushPackageOrderProcessor implements PushPackageOrderProcessor {

    @Resource
    private ThreadPoolExecutor handlerOrderExecutor;

    @Resource
    private RedisService redisService;

    @Resource
    private RedisTemplate<String, String> redisTemplate;


    @Override
    public void sendRequest(List<PhoneOrderWaitPush> phoneOrderWaitPushes) {
        handlerOrderExecutor.execute(() -> executeSend(phoneOrderWaitPushes));
    }

    private void executeSend(List<PhoneOrderWaitPush> phoneOrderWaitPushes) {
        String result = null;
        String pushSize = "";
        List<PushOrderForKxDistribute> pushOrderForKxDistributes = new ArrayList<>(phoneOrderWaitPushes.size());
        for (PhoneOrderWaitPush phoneOrderWaitPush : phoneOrderWaitPushes) {
            pushSize = phoneOrderWaitPush.getPushSite();
            PhoneOrderAvailable pa = phoneOrderWaitPush.getPhoneOrderAvailable();
            PushOrderForKxDistribute pushOrderForKxDistribute = new PushOrderForKxDistribute();
            TreeMap<String, String> signMap = new TreeMap<>();
            signMap.put("a", phoneOrderWaitPush.getAppKey());
            signMap.put("b", phoneOrderWaitPush.getAppId());
            signMap.put("c", pa.getPlatformOrderNo());
            signMap.put("d", pa.getPhoneNum());
            signMap.put("e", pa.getOrderPrice().toPlainString());
            signMap.put("f", pa.getPhoneOperator());
            signMap.put("g", phoneOrderWaitPush.getAppKey());
            String sign = SignUtils.generateSignature(signMap, SignTypeEnum.SHA256);
            pushOrderForKxDistribute.setOrderExpireTime(pa.getOrderExpireTime())
                    .setOrderPrice(pa.getOrderPrice())
                    .setPhoneNum(pa.getPhoneNum())
                    .setPhoneOperator(pa.getPhoneOperator())
                    .setAppId(phoneOrderWaitPush.getAppId())
                    .setSign(sign)
                    .setOrderNo(pa.getPlatformOrderNo())
                    .setProvince(pa.getProvince())
                    .setCity(pa.getCity())
                    .setOrderCreateTime(pa.getCreateTime());
            pushOrderForKxDistributes.add(pushOrderForKxDistribute);
        }
        List<String> orderNos = pushOrderForKxDistributes.stream().map(PushOrderForKxDistribute::getOrderNo).collect(Collectors.toList());
        try {
            log.info("【魁信配单打包】配单推送参数:{}", pushOrderForKxDistributes.toString());
            PushPackageOrderForKxDistribute pushPackageOrderForKxDistribute = new PushPackageOrderForKxDistribute(pushOrderForKxDistributes);
            result = sendRequestForPushOrder(pushSize, pushPackageOrderForKxDistribute);
            log.info("【魁信配单打包】配单推送返回参数:{}", result);
        } catch (Exception e) {
            savePushOrderForException(phoneOrderWaitPushes);
            savePushOrderForSuccess(orderNos);
            log.info("【魁信配单打包】【推单】发送请求出现异常：", e);
        }
        savePushOrderForSuccess(orderNos);
    }

    /**
     * 发送Http请求
     *
     * @param url              请求路径
     * @param pushOrderForKxDistribute 参数
     * @return 响应结果
     */
    private String sendRequestForPushOrder(String url, PushPackageOrderForKxDistribute pushOrderForKxDistribute) {
        Map<String, Object> paramMap = BeanUtil.beanToMap(pushOrderForKxDistribute);
        String paramJson = JSON.toJSONString(paramMap);
        return HttpUtils.jsonPost(url, paramJson);
    }


    /**
     * 放入成功队列
     */
    private void savePushOrderForSuccess(List<String> platformOrderNos) {
        platformOrderNos.forEach(platformOrderNo -> {
            redisTemplate.opsForValue().set(RedisConstant.PUSH_ORDER_WAIT_PUSH_SUCCESS + platformOrderNo, platformOrderNo, 10, TimeUnit.MINUTES);
        });
    }

    /**
     * 放入发送出现异常的队列
     */
    private void savePushOrderForException(List<PhoneOrderWaitPush> phoneOrderWaitPushes) {
        for (PhoneOrderWaitPush phoneOrderWaitPush: phoneOrderWaitPushes) {
            redisService.lPush(RedisConstant.PUSH_ORDER_WAIT_PUSH_EXCEPTION, JSON.toJSONString(phoneOrderWaitPush));
        }
    }
}
